/*
 * Copyright (C) 2021 The Chinese Software International Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.tonyodev.fetch2.database;

import ohos.app.Context;
import ohos.data.DatabaseHelper;
import ohos.data.rdb.RdbStore;
import ohos.data.rdb.ValuesBucket;

import com.tonyodev.fetch2.database.migration.Migration;
import com.tonyodev.fetch2.database.migration.MigrationFiveToSix;
import com.tonyodev.fetch2.database.migration.MigrationFourToFive;
import com.tonyodev.fetch2.database.migration.MigrationOneToTwo;
import com.tonyodev.fetch2.database.migration.MigrationSixToSeven;
import com.tonyodev.fetch2.database.migration.MigrationThreeToFour;
import com.tonyodev.fetch2.database.migration.MigrationTwoToThree;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @since 2021-05-24
 */
public abstract class DownloadDatabase extends DatabaseHelper {


    public DownloadDatabase(Context context) {
        super(context);
    }

    public static final String TABLE_NAME = "requests";
    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_NAMESPACE = "_namespace";
    public static final String COLUMN_URL = "_url";
    public static final String COLUMN_FILE = "_file";
    public static final String COLUMN_GROUP = "_group";
    public static final String COLUMN_PRIORITY = "_priority";
    public static final String COLUMN_HEADERS = "_headers";
    public static final String COLUMN_DOWNLOADED = "_written_bytes";
    public static final String COLUMN_TOTAL = "_total_bytes";
    public static final String COLUMN_STATUS = "_status";
    public static final String COLUMN_ERROR = "_error";
    public static final String COLUMN_NETWORK_TYPE = "_network_type";
    public static final String COLUMN_CREATED = "_created";
    public static final String COLUMN_TAG = "_tag";
    public static final String COLUMN_ENQUEUE_ACTION = "_enqueue_action";
    public static final String COLUMN_IDENTIFIER = "_identifier";
    public static final String COLUMN_DOWNLOAD_ON_ENQUEUE = "_download_on_enqueue";
    public static final String COLUMN_EXTRAS = "_extras";
    public static final String COLUMN_AUTO_RETRY_MAX_ATTEMPTS = "_auto_retry_max_attempts";
    public static final String COLUMN_AUTO_RETRY_ATTEMPTS = "_auto_retry_attempts";
    public static final int OLD_DATABASE_VERSION = 6;
    public static final int DATABASE_VERSION = 7;

    public static final String CUTTING_LINE_KEY = "#key#";  //分割线
    public static final String CUTTING_LINE = "#content#";  //分割线


    public static ValuesBucket downloadInfo2ValuesBucket(DownloadInfo downloadInfo) {
        ValuesBucket valuesBucket = new ValuesBucket();
        valuesBucket.putInteger(COLUMN_ID, downloadInfo.getId());
        valuesBucket.putString(COLUMN_NAMESPACE, downloadInfo.getNamespace());
        valuesBucket.putString(COLUMN_URL, downloadInfo.getUrl());
        valuesBucket.putString(COLUMN_FILE, downloadInfo.getFile());
        valuesBucket.putInteger(COLUMN_GROUP, downloadInfo.getGroup());
        if (downloadInfo.getPriority() != null) {
            valuesBucket.putInteger(COLUMN_PRIORITY, downloadInfo.getPriority().getValue());
        }
        if (downloadInfo.getHeaders() != null) {
            Set<String> key = downloadInfo.getHeaders().keySet();
            StringBuffer sb = new StringBuffer();
            for (String info : key) {
                sb.append(info);
                sb.append(CUTTING_LINE_KEY);
                sb.append(downloadInfo.getHeaders().get(info));
                sb.append(CUTTING_LINE);
            }
            valuesBucket.putString(COLUMN_HEADERS, sb.toString());
        }
        valuesBucket.putLong(COLUMN_DOWNLOADED, downloadInfo.getDownloaded());
        valuesBucket.putLong(COLUMN_TOTAL, downloadInfo.getTotal());
        if (downloadInfo.getStatus() != null) {
            valuesBucket.putInteger(COLUMN_STATUS, downloadInfo.getStatus().getValue());
        }
        if (downloadInfo.getError() != null) {
            valuesBucket.putInteger(COLUMN_ERROR, downloadInfo.getError().getValue());
        }
        if (downloadInfo.getNetworkType() != null) {
            valuesBucket.putInteger(COLUMN_NETWORK_TYPE, downloadInfo.getNetworkType().getValue());
        }
        valuesBucket.putLong(COLUMN_CREATED, downloadInfo.getCreated());
        valuesBucket.putString(COLUMN_TAG, downloadInfo.getTag());
        if (downloadInfo.getEnqueueAction() != null) {
            valuesBucket.putInteger(COLUMN_ENQUEUE_ACTION, downloadInfo.getEnqueueAction().getValue());
        }
        valuesBucket.putLong(COLUMN_IDENTIFIER, downloadInfo.getIdentifier());
        if (downloadInfo.getDownloadOnEnqueue()) {
            valuesBucket.putInteger(COLUMN_DOWNLOAD_ON_ENQUEUE, 1);
        } else {
            valuesBucket.putInteger(COLUMN_DOWNLOAD_ON_ENQUEUE, 0);
        }
        if (downloadInfo.getExtras() != null) {
            valuesBucket.putString(COLUMN_EXTRAS, downloadInfo.getExtras().toJSONString());
        }
        valuesBucket.putInteger(COLUMN_AUTO_RETRY_MAX_ATTEMPTS, downloadInfo.getAutoRetryMaxAttempts());
        valuesBucket.putInteger(COLUMN_AUTO_RETRY_ATTEMPTS, downloadInfo.getAutoRetryAttempts());

        return valuesBucket;
    }

    public abstract DownloadDao requestDao();

    public abstract RdbStore getRdbStore();

    public static List<Migration> getMigrations() {
        ArrayList<Migration> migrations = new ArrayList<>();
        migrations.add(new MigrationOneToTwo());
        migrations.add(new MigrationTwoToThree());
        migrations.add(new MigrationThreeToFour());
        migrations.add(new MigrationFourToFive());
        migrations.add(new MigrationFiveToSix());
        migrations.add(new MigrationSixToSeven());
        return migrations;
    }
}
